package com.adminx.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class ModelAndView {
    private Logger logger = LogManager.getLogger(ModelAndView.class) ;
    public static final String JSON_CONTENT_TYPE = "application/json;charset=utf-8" ;
    /**
     * the jackson mapper for json processing.
     */
    private static ObjectMapper jsonMapper = new ObjectMapper() ;

    private HttpServletRequest req  ;
    private HttpServletResponse resp ;
    private String view ;
    private Map<String, Object> model ;

    public ModelAndView() {
        this.model = new HashMap<>() ;
    }

    public ModelAndView(HttpServletResponse resp) {
        this.model = new HashMap<>() ;
        this.resp = resp ;
    }

    public ModelAndView addAttribute(String attrName, Object valueObj) {
        this.model.put(attrName, valueObj) ;
        return this ;
    }

    /**
     * object to json string
     * @return
     * @throws JsonProcessingException
     */
    public String toJsonString() throws JsonProcessingException {
        return jsonMapper.writeValueAsString(this.model) ;
    }

    /**
     * return the response
     */
    public void response() {
        resp.setContentType(JSON_CONTENT_TYPE) ;
        try {
            PrintWriter out = resp.getWriter();
            out.write(toJsonString());
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    public static ModelAndView buildSuccess(HttpServletResponse resp) {
        ModelAndView mv = new ModelAndView(resp) ;
        mv.addAttribute("code", ActionStatus.OK) ;
        return mv ;
    }
    public static ModelAndView buildFailed(HttpServletResponse resp) {
        ModelAndView mv = new ModelAndView(resp) ;
        mv.addAttribute("code", ActionStatus.FAIL) ;
        return mv ;
    }
    public static ModelAndView buildFailed(HttpServletResponse resp, String failedMsg) {
        ModelAndView mv = new ModelAndView(resp) ;
        mv.addAttribute("code", ActionStatus.FAIL)
                .addAttribute("msg", failedMsg) ;
        return mv ;
    }

    /**
     * read data from Request in json
     * @param req
     * @param clazz
     * @param <T>
     * @return
     */
    public static  <T> T readRequestData(HttpServletRequest req, Class<T> clazz) {
        BufferedReader reader = null ;
        StringBuilder stringBuilder = new StringBuilder() ;
        String line = null ;
        T obj = null ;
        try {
            reader = req.getReader() ;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line) ;
            }
            obj = jsonMapper.readValue(stringBuilder.toString(), clazz) ;
        } catch (IOException e) {
           System.err.println("[ERROR] parse request data error.") ;
        }
        return obj ;
    }








}
